//
//  UIView+Shadow.m
//  WangMaBorrowArchitecture
//
//  Created by ming tan on 2019/3/7.
//  Copyright © 2019 ming tan. All rights reserved.
//

#import "UIView+Shadow.h"
//配置圆角
#define __kCornerRadius__ 9
#define __kColorLine__  @"797979"
@implementation UIView (Shadow)
- (void) forceClips{
    [self setNeedsLayout];
    [self layoutIfNeeded];
}
- (UIView*)subViewOfClassName:(NSString*)className {
    for (UIView* subView in self.subviews) {
        if ([NSStringFromClass(subView.class) isEqualToString:className]) {
            return subView;
        }
        
        UIView* resultFound = [subView subViewOfClassName:className];
        if (resultFound) {
            return resultFound;
        }
    }
    return nil;
}
- (void)addGeneralShadow {
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowOffset = CGSizeMake(0, 0);
    self.layer.cornerRadius = __kCornerRadius__;
    self.layer.shadowOpacity = 0.8;
    self.layer.shadowRadius = 3;
}
- (void)addGeneralShadow:(UIColor *)color WithRadius:(CGFloat)cornerRadius WithShadowRadius:(CGFloat)shodowRadius WithHere:(int)here{
    self.layer.shadowColor = color.CGColor;
    self.layer.shadowOffset = CGSizeMake(0, 0);
    self.layer.cornerRadius = cornerRadius;
    self.layer.shadowOpacity = 0.8;
    self.layer.shadowRadius = shodowRadius;
    
    if (here == 3) {
        float shadowPathWidth = self.layer.shadowRadius;
        CGRect shadowRect = CGRectMake(5, self.height-10, self.width-10, shadowPathWidth);
        UIBezierPath *path = [UIBezierPath bezierPathWithRect:shadowRect];
        self.layer.shadowPath = path.CGPath;
    }
   
    
}
- (void)addTopGeneralShadow {
    self.layer.shadowOffset = CGSizeMake(0, 0); //设置偏移量为0,四周都有阴影
    self.layer.shadowRadius = 1.0f;//阴影半径，默认3
    self.layer.shadowOpacity = 0.25f;//阴影透明度，
    self.layer.masksToBounds = NO;
    self.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.layer.cornerRadius].CGPath;
    self.layer.shadowColor = [UIColor colorWithHexString:__kColorLine__].CGColor;
    self.layer.cornerRadius=__kCornerRadius__;
}

- (void)addCorner:(CGFloat)cornerRadius {
    self.layer.masksToBounds = YES;
    self.layer.cornerRadius = cornerRadius;
}
- (void)addCorner:(CGFloat)cornerRadius AndLine:(UIColor *)color {
    self.layer.masksToBounds = YES;
    self.layer.cornerRadius = cornerRadius;
    self.layer.borderWidth = 1;
    self.layer.borderColor = color.CGColor;
}

- (void)addLine:(UIColor *)color AndLineWidth:(CGFloat)width {
    self.layer.masksToBounds = YES;
    self.layer.borderWidth = width;
    self.layer.borderColor = color.CGColor;
    self.layer.cornerRadius = 18;
}
- (void)addTopCorner {
    UIBezierPath *cornerRadiusPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopRight | UIRectCornerTopLeft cornerRadii:CGSizeMake(__kCornerRadius__, __kCornerRadius__)];
    
    CAShapeLayer *cornerRadiusLayer = [ [CAShapeLayer alloc ] init];
    cornerRadiusLayer.frame = self.bounds;
    cornerRadiusLayer.path = cornerRadiusPath.CGPath;
    self.layer.mask = cornerRadiusLayer;
}
- (void)customizedCornerTopLeft:(CGFloat)topLeft topRight:(CGFloat)topRight bottomLeft:(CGFloat)bottomLeft bottomRight:(CGFloat)bottomRight {

    UIBezierPath *path = [UIBezierPath bezierPath];
    CGFloat height = self.bounds.size.height;
    CGFloat width = self.bounds.size.width;
    //左下
    [path moveToPoint:CGPointMake(topLeft, 0)];
    [path addQuadCurveToPoint:CGPointMake(0, topLeft) controlPoint:CGPointZero];
    //左上
    [path addLineToPoint:CGPointMake(0, height - bottomLeft)];
    [path addQuadCurveToPoint:CGPointMake(bottomLeft, height) controlPoint:CGPointMake(0, height)];
    //右上
    [path addLineToPoint:CGPointMake(width - bottomRight, height)];
    [path addQuadCurveToPoint:CGPointMake(width, height - bottomRight) controlPoint:CGPointMake(width, height)];
    //右下
    [path addLineToPoint:CGPointMake(width, topRight)];
    [path addQuadCurveToPoint:CGPointMake(width - topRight, 0) controlPoint:CGPointMake(width, 0)];
    [path closePath];
    [path addClip];
    
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;
    maskLayer.path = path.CGPath;
    self.layer.mask = maskLayer;
}
- (void)addShowAnimation {
    self.hidden = NO;
    self.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1);
    [UIView animateWithDuration:0.5 animations:^{
        self.layer.transform = CATransform3DMakeScale(1, 1, 1);
    } completion:^(BOOL finished) {
        
    }];
    
}
- (void)addDissAnimation {
    self.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1);
    [UIView animateWithDuration:0.3 animations:^{
        self.layer.transform = CATransform3DMakeScale(1, 1, 1);
    } completion:^(BOOL finished) {
        self.hidden = YES;
    }];
}
#pragma mark ----  渐变
- (void)addStartPoint:(CGPoint)startPoint AndendPoint:(CGPoint)endPoint AndColors:(NSArray *)colors {
    [self forceClips];
     CAGradientLayer * gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.bounds;
    gradientLayer.colors = colors;
    gradientLayer.startPoint = startPoint;
    gradientLayer.endPoint = endPoint;
    gradientLayer.locations = @[@0, @1];
    [self.layer addSublayer:gradientLayer];
}



- (void)shakeWithShakeDirection:(QHLDirection)shakeDirection {
    [self shakeWithTimes:10 speed:0.05 range:5 shakeDirection:shakeDirection];
}

- (void)shakeWithTimes:(NSInteger)times shakeDirection:(QHLDirection)shakeDirection {
    [self shakeWithTimes:times speed:0.05 range:5 shakeDirection:shakeDirection];
}
- (void)shakeWithTimes:(NSInteger)times speed:(CGFloat)speed shakeDirection:(QHLDirection)shakeDirection {
    [self shakeWithTimes:times speed:speed range:5 shakeDirection:shakeDirection];
}

- (void)shakeWithTimes:(NSInteger)times speed:(CGFloat)speed range:(CGFloat)range shakeDirection:(QHLDirection)shakeDirection {
    [self viewShakesWithTiems:times speed:speed range:range shakeDirection:shakeDirection currentTimes:0 direction:1];
}
/**
      *  @param times          震动的次数
      *  @param speed          震动的速度
      *  @param range          震动的幅度
      *  @param shakeDirection 哪个方向上的震动
      *  @param currentTimes   当前的震动次数
      *  @param direction      向哪边震动
      */
- (void)viewShakesWithTiems:(NSInteger)times speed:(CGFloat)speed range:(CGFloat)range shakeDirection:(QHLDirection)shakeDirection currentTimes:(NSInteger)currentTimes direction:(int)direction{
    
    [UIView animateWithDuration:speed animations:^{
        self.transform = (shakeDirection == QHLDirectionHorizontal)? CGAffineTransformMakeTranslation(range * direction, 0):CGAffineTransformMakeTranslation(0, range * direction);
    } completion:^(BOOL finished) {
        if (currentTimes >= times) {
            [UIView animateWithDuration:speed animations:^{
                self.transform = CGAffineTransformIdentity;
            }];
            return;
        }
#pragma mark - 循环到times == currentTimes时候 会跳出该方法
        [self viewShakesWithTiems:times - 1
                            speed:speed
                            range:range
                   shakeDirection:shakeDirection
                     currentTimes:currentTimes + 1
                        direction:direction * -1];
    }];
}


/**
 *  设置可变的圆角和边框
 *
 *  @param rect
 *  @param view
 *  @param BD          需要显示边框的方向
 *  @param corners     需要设置圆角的方向
 *  @param radius      圆角角度
 *  @param borderWidth 边框的宽度
 *  @param borderColor 边框的颜色
 */
-( void)setVariableRoundedBorder:(CGRect)rect view:(UIView *)view  BD:(BorderDirection)BD corners:(UIRectCorner)corners radius:(CGFloat)radius borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor {
    
    if (corners != 0) {
        [self setRounded:rect view:self corners:corners];
    }
    if (BD != 0) {
        [self drawInContext:UIGraphicsGetCurrentContext() view:view BD:BD corners:corners radius:radius borderWidth:borderWidth borderColor:borderColor];
    }
    
}
 
/**
 *  设置圆角
 *
 *  @param rect
 *  @param view
 *  @param corners 需要设置圆角的方向
 */
- (void)setRounded:(CGRect)rect view:(UIView *)view corners:(UIRectCorner)corners{
    UIBezierPath* maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:CGSizeMake(6, 6)];
    maskPath.lineWidth     = 0.f;
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view.bounds;
    maskLayer.path = maskPath.CGPath;
    view.layer.mask = maskLayer;
}
 
-(void)drawInContext:(CGContextRef)context view:(UIView *)view BD:(BorderDirection)BD corners:(UIRectCorner)corners radius:(CGFloat)radius borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor{
    
    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetShouldAntialias(context, true);
    
    CGContextSetLineWidth(context, borderWidth);
    CGRect rrect = view.bounds;
    CGFloat height = rrect.size.height;
    CGFloat width = rrect.size.width;
    [borderColor set];
    NSInteger BorderDirectionNumber = 0;
 
    if (BD & BorderDirectionLeft) {
        BorderDirectionNumber++;
    }
    if (BD & BorderDirectionRight) {
        BorderDirectionNumber++;
    }
    if (BD & BorderDirectionBottom) {
        BorderDirectionNumber++;
    }
    if (BD & BorderDirectionTop) {
        BorderDirectionNumber++;
    }
    if (BorderDirectionNumber == 4) {
        CGContextMoveToPoint(context, 0, 0);
        CGContextAddArcToPoint(context, 0, height, width, height, radius);
        CGContextAddArcToPoint(context, width, height, width, 0, radius);
        CGContextAddArcToPoint(context,  width, 0, 0, 0, radius);
        CGContextAddArcToPoint(context,  0, 0, 0, height, radius);
        CGContextStrokePath(context);
    }else if (BorderDirectionNumber == 3){
        if (BD & BorderDirectionLeft && BD & BorderDirectionBottom && BD & BorderDirectionRight) {
            [self drawThreeSide:context radius:radius oneX:0 oneY:0 twoX:0 twoY:height threeX:width threeY:height foruX:width foruY:0];
            
        }else if (BD & BorderDirectionLeft && BD & BorderDirectionBottom && BD & BorderDirectionTop){
            [self drawThreeSide:context radius:radius oneX:width oneY:0 twoX:0 twoY:0 threeX:0 threeY:height foruX:width foruY:height];
            
        }else if (BD & BorderDirectionBottom && BD & BorderDirectionRight && BD & BorderDirectionTop){
            [self drawThreeSide:context radius:radius oneX:0 oneY:height twoX:width twoY:height threeX:width threeY:0 foruX:0 foruY:0];
            
        }else if (BD & BorderDirectionLeft && BD & BorderDirectionRight && BD & BorderDirectionTop){
            [self drawThreeSide:context radius:radius oneX:0 oneY:height twoX:0 twoY:0 threeX:width threeY:0 foruX:width foruY:height];
            
        }
    }else if (BorderDirectionNumber == 2){
        if (BD & BorderDirectionLeft && BD & BorderDirectionBottom) {
            [self drawTwoSide:context radius:radius oneX:0 oneY:0 twoX:0 twoY:height threeX:width threeY:height foruX:width foruY:0];
        }else if (BD & BorderDirectionLeft && BD & BorderDirectionRight){
            CGContextMoveToPoint(context, 0, 0);
            CGContextAddLineToPoint(context, 0, height);
            CGContextStrokePath(context);
            CGContextMoveToPoint(context, width, 0);
            CGContextAddLineToPoint(context, width, height);
            CGContextStrokePath(context);
        }else if (BD & BorderDirectionLeft && BD & BorderDirectionTop){
            [self drawTwoSide:context radius:radius oneX:0 oneY:height twoX:0 twoY:0 threeX:width threeY:0 foruX:width foruY:height];
        }else if (BD & BorderDirectionBottom && BD & BorderDirectionRight){
            [self drawTwoSide:context radius:radius oneX:0 oneY:height twoX:width twoY:height threeX:width threeY:0 foruX:0 foruY:0];
        }else if (BD & BorderDirectionBottom && BD & BorderDirectionTop){
            CGContextMoveToPoint(context, 0, 0);
            CGContextAddLineToPoint(context, width, 0);
            CGContextStrokePath(context);
            CGContextMoveToPoint(context, 0, height);
            CGContextAddLineToPoint(context, width, height);
            CGContextStrokePath(context);
        }else if (BD & BorderDirectionRight && BD & BorderDirectionTop){
            [self drawTwoSide:context radius:radius oneX:0 oneY:0 twoX:width twoY:height threeX:width threeY:height foruX:0 foruY:height];
        }
    }else if (BorderDirectionNumber == 1){
        if (BD & BorderDirectionLeft) {
            CGContextMoveToPoint(context, 0, 0);
            CGContextAddLineToPoint(context, 0, height);
            CGContextStrokePath(context);
        }else if (BD & BorderDirectionRight){
            CGContextMoveToPoint(context, width, 0);
            CGContextAddLineToPoint(context, width, height);
            CGContextStrokePath(context);
        }else if (BD & BorderDirectionTop){
            CGContextMoveToPoint(context, 0, 0);
            CGContextAddLineToPoint(context, width, 0);
            CGContextStrokePath(context);
        }else if (BD & BorderDirectionBottom){
            CGContextMoveToPoint(context, 0, height);
            CGContextAddLineToPoint(context, width, height);
            CGContextStrokePath(context);
        }
    }
}
 
- (void)drawThreeSide:(CGContextRef)context radius:(CGFloat)radius oneX:(CGFloat)oneX  oneY:(CGFloat)oneY twoX:(CGFloat)twoX  twoY:(CGFloat)twoY threeX:(CGFloat)threeX threeY:(CGFloat)threeY foruX:(CGFloat)foruX foruY:(CGFloat)foruY{
    CGContextMoveToPoint(context, oneX, oneY);
    CGContextAddArcToPoint(context, twoX, twoY, threeX, threeY, radius);
    CGContextAddArcToPoint(context, threeX, threeY, foruX, foruY, radius);
    CGContextAddArcToPoint(context,  foruX, foruY, oneX, oneY, 0);
    CGContextStrokePath(context);
}
 
- (void)drawTwoSide:(CGContextRef)context radius:(CGFloat)radius oneX:(CGFloat)oneX  oneY:(CGFloat)oneY twoX:(CGFloat)twoX  twoY:(CGFloat)twoY threeX:(CGFloat)threeX threeY:(CGFloat)threeY foruX:(CGFloat)foruX foruY:(CGFloat)foruY{
    CGContextMoveToPoint(context, oneX, oneY);
    CGContextAddArcToPoint(context, twoX, twoY, threeX, threeY, radius);
    CGContextAddArcToPoint(context, threeX, threeY, foruX, foruY, 0);
    CGContextStrokePath(context);
}
// 判断View是否显示在屏幕上
- (BOOL)isDisplayedInScreen
{
    if (self == nil) {
        return FALSE;
    }
    
    CGRect screenRect = [UIScreen mainScreen].bounds;
    
    // 转换view对应window的Rect
    CGRect rect = [self convertRect:self.frame fromView:nil];
    if (CGRectIsEmpty(rect) || CGRectIsNull(rect)) {
        return FALSE;
    }
    
    // 若view 隐藏
    if (self.hidden) {
        return FALSE;
    }
    
    // 若没有superview
    if (self.superview == nil) {
        return FALSE;
    }
    
    // 若size为CGrectZero
    if (CGSizeEqualToSize(rect.size, CGSizeZero)) {
        return  FALSE;
    }
    
    // 获取 该view与window 交叉的 Rect
    CGRect intersectionRect = CGRectIntersection(rect, screenRect);
    if (CGRectIsEmpty(intersectionRect) || CGRectIsNull(intersectionRect)) {
        return FALSE;
    }
    
    return TRUE;
}

-(void)addTopBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
    
    CALayer *border = [CALayer layer];
    
    border.backgroundColor = color.CGColor;
    
    border.frame = CGRectMake(0, 0, self.frame.size.width, borderWidth);
    
    [self.layer addSublayer:border];
    
}

-(void)addBottomBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
    
    CALayer *border = [CALayer layer];
    
    border.backgroundColor = color.CGColor;
    
    border.frame = CGRectMake(0, self.frame.size.height - borderWidth, self.frame.size.width, borderWidth);
    
    [self.layer addSublayer:border];
    
}

-(void)addLeftBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
    
    CALayer *border = [CALayer layer];
    
    border.backgroundColor = color.CGColor;
    
    border.frame = CGRectMake(0, 0, borderWidth, self.frame.size.height);
    
    [self.layer addSublayer:border];
    
}

-(void)addRightBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
    
    CALayer *border = [CALayer layer];
    
    border.backgroundColor = color.CGColor;
    
    border.frame = CGRectMake(self.frame.size.width - borderWidth, 0, borderWidth, self.frame.size.height);
    
    [self.layer addSublayer:border];
    
}

@end
